/*
 * md5.h
 * md5 header
 *
 * @auther Miles Dung
 * @date May 26 2011
 *
 * This file is part of md5 net based cracker project, which
 * released under the GNU GPL v2 or v3 (whichever you like)
 * This project is distributed in the hope that it will be
 * useful, but WITHOUT ANY WARRANTY, without even the implied
 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 * PURPOSE. See the GNU General Public License for more details.
 */
#ifndef MD5_H_INCLUDED
#define MD5_H_INCLUDED
#include <fstream>
#include <sstream>
#include <iostream>
#include <cstring>
#include <cstdlib>

using namespace std;
#define X86
#ifdef X86
typedef long long int UINT64;
typedef unsigned int UINT32;
typedef unsigned short UINT16;
typedef unsigned char UINT8;
#endif

class md5
{
public:
    md5(string& str);
    md5(ifstream& fin);
    void md5_init();
    void md5_calc();
    string md5_get_hash();
private:
    //four chaining varibles
    const static UINT32 A=0x67452301;
    const static UINT32 B=0xefcdab89;
    const static UINT32 C=0x98badcfe;
    const static UINT32 D=0x10325476;

    UINT32 a, b, c, d;

    union md5_dig_t
    {
        UINT8  dig8[64];
        UINT16 dig16[32];
        UINT32 dig32[16];
        UINT64 dig64[8];
    } digest;

    union md5_res_t
    {
        UINT8 res8[16];
        UINT32 res32[4];
    } result;

    inline UINT32 F(UINT32 X,UINT32 Y,UINT32 Z);
    inline UINT32 G(UINT32 X,UINT32 Y,UINT32 Z);
    inline UINT32 H(UINT32 X,UINT32 Y,UINT32 Z);
    inline UINT32 I(UINT32 X,UINT32 Y,UINT32 Z);

    inline void FF(UINT32& a, UINT32 b, UINT32 c, UINT32 d,
                   UINT32 Mj, UINT32 s, UINT32 ti);
    inline void GG(UINT32& a, UINT32 b, UINT32 c, UINT32 d,
                   UINT32 Mj, UINT32 s, UINT32 ti);
    inline void HH(UINT32& a, UINT32 b, UINT32 c, UINT32 d,
                   UINT32 Mj, UINT32 s, UINT32 ti);
    inline void II(UINT32& a, UINT32 b, UINT32 c, UINT32 d,
                   UINT32 Mj, UINT32 s, UINT32 ti);
};

#endif // MD5_H_INCLUDED
